﻿using System;
using System.Globalization;
using BikeBouncer.BusinessLayer;
using BikeBouncer.BusinessLayer.Entities;
using BikeBouncer.BusinessLayer.Enums;
using BikeBouncer.Site.Enums;
using Devv.Core.Utils;

namespace BikeBouncer.Site
{
	public partial class Register_aspx : BasePage
	{
		#region Page methods

		protected void Page_Load(Object sender, EventArgs e)
		{
			if (!Page.IsPostBack)
			{
				FirstLoad();
			}
			else
			{
				if (ChkItemWasStolen.Checked)
				{
					ClientScript.RegisterStartupScript(typeof(String), "DivWasStolen", "$('#DivWasStolen').slideDown(defaultSlideSpeed);", true);
				}
			}
		}

		private void FirstLoad()
		{
			RegisterScript(ScriptSource.ToolTips);
			RegisterScript(ScriptSource.ColorBox);

			AjaxManager.SetDefaults_AutoCompleteExtender(AutoComplete_TxtItemMaker);
			AjaxManager.SetDefaults_AutoCompleteExtender(AutoComplete_TxtNoteCity);
			AjaxManager.SetDefaults_CalendarExtender(Calendar_TxtNoteDate);

			FooterAds.Source = AdSource.EvansCycles;

			ChkItemNotStolen.Attributes.Add("onclick", "$('#DivWasStolen').slideUp(defaultSlideSpeed);");
			ChkItemWasStolen.Attributes.Add("onclick", "$('#DivWasStolen').slideDown(defaultSlideSpeed);");
			ValTxtUserEmail.ValidationExpression = RegexUtil.Email;
			TxtNoteDate.Text = DateTime.Now.AddDays(-1).ToString("dd/MM/yyyy");

			PanRegistered.Visible = false;

			if (SessionManager.LoggedUser != null && SessionManager.LoggedUser.Id > 0)
			{
				String name = SessionManager.LoggedUser.DisplayName;
				if (name == String.Empty) name = SessionManager.LoggedUser.Email;

				LitLoggedName.Text = LitLoggedName.Text.Replace("#",name);
				LitLoggedEmail.Text = SessionManager.LoggedUser.Email;

				PanLoginDetails.Visible = false;
			}
			else
			{
				PanUserLogged.Visible = false;
			}
		}

		#endregion

		#region Register

		protected void ButRegister_Click(Object sender, EventArgs e)
		{
			Page.Validate();

			if (Page.IsValid)
			{
				TxtItemTitle.Text = TxtItemTitle.Text.Trim();
				TxtItemMaker.Text = TxtItemMaker.Text.Trim();
				TxtUserEmail.Text = TxtUserEmail.Text.Trim();
				TxtUserPassword.Text = TxtUserPassword.Text.Trim();

				Register();
			}
			else
			{
				AppendError(GetGlobalString("PageNotValid"));
			}
		}

		private void Register()
		{
			Maker maker = RegisterMaker();
			User user = RegisterUser();

			if (maker == null || user == null)
			{
				return;
			}

			Item item = RegisterItem(maker, user);

			if (item == null)
			{
				return;
			}
			
			PanForm.Visible = false;
			PanRegistered.Visible = true;
			LitCongratsNewUser.Visible = user.RegDate > DateTime.Now.AddMinutes(-1);

			H1 = GetGlobalString("Congratulations") + "!";

			if (ChkItemWasStolen.Checked)
			{
				Address address;

				if (!String.IsNullOrEmpty(TxtNotePostcode.Text) || !String.IsNullOrEmpty(TxtNoteLocation.Text) || !String.IsNullOrEmpty(TxtNoteCity.Text))
				{
					address = RegisterNoteAddress(user);
				}
				else
				{
					address = new Address();
				}

				Note note = RegisterNote(item, address);

				if (note == null)
				{
					AppendError(GetLocalResourceObject("Error_CantAddNote").ToString());
				}
			}
		}

		private Maker RegisterMaker()
		{
			try
			{
				Maker maker = new Maker();
				maker.Construct(DataAccess.Maker_Get(TxtItemMaker.Text));

				if (maker.Id < 1)
				{
					TxtItemMaker.Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(TxtItemMaker.Text);

					maker.Title = TxtItemMaker.Text;
					maker.Active = true;

					DataAccess.Maker_Upsert(maker);
				}

				return maker;
			}
			catch (Exception ex)
			{
				ErrorManager.Log(ex, "Error trying to fetch or register a new maker.");
				AppendError(ex, "Maker");

				return null;
			}
		}

		private User RegisterUser()
		{
			if (SessionManager.LoggedUser != null && SessionManager.LoggedUser.Id > 0)
			{
				return SessionManager.LoggedUser;
			}

			try
			{
				User user = new User();
				user.Construct(DataAccess.User_Get(TxtUserEmail.Text, EntityStatus.All));

				if (user.Id < 1)
				{
					user.Email = TxtUserEmail.Text;
					user.Password = TxtUserPassword.Text;
					user.Active = true;

					DataAccess.User_Upsert(user);
					SessionManager.LoggedUser = user;
					
					return user;
				}

				if (user.PasswordHash == BusinessLayer.Entities.User.GetPasswordHash(TxtUserEmail.Text, TxtUserPassword.Text))
				{
					return user;
				}

				String link = "<a href=\"/ForgotPassword.aspx\" title=\"" + GetLocalResourceObject("LinkForgotPassword.ToolTip") + "\">" + GetLocalResourceObject("LinkForgotPassword.Text") + "</a>";
				String error = GetLocalResourceObject("Error_InvalidPassword").ToString();
				error = error.Replace("#EMAIL", user.Email);
				error = error.Replace("#PASSWORDLINK", link);

				AppendError(error);

				return null;
			}
			catch (Exception ex)
			{
				ErrorManager.Log(ex, "Error trying to login or register a new user.");
				AppendError(ex, "User");

				return null;
			}
		}

		private Item RegisterItem(Maker maker, User user)
		{
			try
			{
				Item item = new Item();
				Item matched = new Item();

				item.Maker = maker;
				item.User = user;
				item.Title = TxtItemTitle.Text;
				item.Serial = TxtItemSerial.Text;
				item.Active = true;

				item.Status = ChkItemWasStolen.Checked ? ItemStatus.Stolen : ItemStatus.Registered;

				if (!String.IsNullOrEmpty(item.Serial))
				{
					matched.Construct(DataAccess.Item_GetBySerial(item.Serial));
				}

				if (matched.Id > 0)
				{
					String itemMaker = item.Maker.Title.ToLower();
					String txtMaker = TxtItemMaker.Text.ToLower();

					if (itemMaker.Contains(txtMaker) || txtMaker.Contains(itemMaker))
					{
						String link = "<a href=\"/Contact.aspx?subject=Duplicated item\" title=\"" + GetLocalResourceObject("LinkContact.ToolTip") + "\">" + GetLocalResourceObject("LinkContact.Text") + "</a>";
						String error = GetLocalResourceObject("Error_SerialExists").ToString();
						error = error.Replace("#SERIAL", item.Serial);
						error = error.Replace("#LINKCONTACT", link);

						AppendError(error);

						MailManager.RegistrationDuplicateSerial(item, matched);

						return null;
					}
				}

				DataAccess.Item_Upsert(item);
                
				return item;
			}
			catch (Exception ex)
			{
				ErrorManager.Log(ex, "Error trying to register a new item.");
				AppendError(ex, "Item");

				return null;
			}
		}

		private Address RegisterNoteAddress(User user)
		{
			try
			{
				Address address = new Address();

				address.UserId = user.Id;
				address.Postcode = TxtNotePostcode.Text;
				address.Location = TxtNoteLocation.Text;
				address.Active = true;

				address.City = City.Fetch(TxtNoteCity.Text);

				if (String.IsNullOrEmpty(address.City.Country))
				{
					address.City.Country = SessionManager.CurrentCountry;
				}
				
				DataAccess.Address_Upsert(address);

				return address;
			}
			catch (Exception ex)
			{
				ErrorManager.Log(ex, "Error trying to register the note address.");
				AppendError(ex, "Address");

				return null;
			}
		}

		private Note RegisterNote(Item item, Address address)
		{
			try
			{
				Note note = new Note();

				note.Item = item;
				note.Address = address;
				note.IP = LocationManager.RequestIP; 
				note.Details = TxtNoteDetails.Text;
				note.ReferenceDate = DataUtil.GetDateTime(TxtNoteDate.Text); 
				note.Active = true;
				
				DataAccess.Note_Insert(note);

				return note;
			}
			catch (Exception ex)
			{
				ErrorManager.Log(ex, "Error trying to register a new note.");
				AppendError(ex, "Note");

				return null;
			}
		}

		#endregion
	}
}